package ASWebDavTest 
{
	import air.update.descriptors.ConfigurationDescriptor;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.FileReference;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.utils.ByteArray;

	public class RemoteFile extends BaseFile
	{
		protected var xmlNode:XML;
		protected var depth:int;
		protected var loadedCount:int = 0;
		
		public function RemoteFile(Parent:BaseFile, XmlNode:XML, Url:String)
		{
			super(Parent);
			
			if(XmlNode != null)
				this.xmlNode = XmlNode;
			
			if(Url != null)
				this.Url = Url;
		}
		
		public override function get Url():String
		{
			//trace("Url() xmlNode=" + xmlNode);
			if (super.Url != null)
				return super.Url;
			var url:String = String(xmlNode.*::href);
			return RootUrl + url;
		}
		public override function set Url(value:String):void
		{
			super.Url = value;
			if (xmlNode != null)
				xmlNode.*::href = value;
		}
		
		public function get RootUrl():String
		{
			var url:String = Patriarch.Url;
			var idx:int = url.indexOf("//");
			idx += url.substr(idx + 2).indexOf("/", idx) + 2;
			return url.substr(0, idx);
		}
		
		public function get RelativeUrl():String
		{
			var url:String = Url;
			if (url.indexOf("//") >= 0)
				url = url.substr(RootUrl.length);
			return url;
		}
		
		public function get XmlNode():XML
		{
			if (xmlNode == null)
				Load(1);
			return xmlNode;
		}
		
		public function get RemoteParent():RemoteFile
		{
			return Parent as RemoteFile;
		}
		
		public override function get Name():String
		{
			var name:String = Url;
			if (Parent != null)
				name = name.substr(RemoteParent.Url.length);
			return name;
		}
		
		public function get name():String
		{
			return Name;
		}
		
		public function get label():String
		{
			return Name;
		}
		
		public override function get SizeBytes():int
		{
			return parseInt(xmlNode.*::propstat[0].*::prop[0].*::getcontentlength);
		}
		
		public override function get CreatedUtc():Date
		{
			return new Date(xmlNode.*::propstat[0].*::prop[0].*::creationdate);
		}
		
		public override function get ModifiedUtc():Date
		{
			return new Date(xmlNode.*::propstat[0].*::prop[0].*::getlastmodified);
		}
		
		public override function get IsFolder():Boolean
		{
			return xmlNode.*::propstat[0].*::prop[0].*::resourcetype[0].*::collection[0] != null;
		}
		
		public override function Load(depth:int):void
		{
			if (depth <= 0)
				return;
			this.depth = depth;
			
			// Send request
			if (xmlNode != null && IsFolder == false)
				beenLoaded = true; // No need to recurse files
			if (xmlNode == null || beenLoaded == false)
			{
				beenLoaded = true;
				
				var request:URLRequest = new URLRequest(Url);
				request.method = "PROPFIND";
				request.requestHeaders.push(new URLRequestHeader("Depth", "1"));
				request.contentType = "text/xml";
				request.data = "<?xml version=\"1.0\" ?><D:propfind xmlns:D=\"DAV:\"><D:allprop/></D:propfind>";
				
				// Read response
				//loader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, OnResponse);
				var loader:URLLoader = new URLLoader();
				loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, OnStatus);
				loader.addEventListener(IOErrorEvent.IO_ERROR, OnError);
				loader.addEventListener(ProgressEvent.PROGRESS, OnProgress);
				loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
				loader.addEventListener(Event.COMPLETE, OnComplete);
				loader.load(request);	
			}
		}
		
		protected function OnComplete(e:Event=null):void
		{
			trace("OnComplete");
			var text:String = e.target.data as String;
			var doc:XML = XML(text);

			// Load self & children
			for each(var node:XML in doc.children())
			{
				if (xmlNode == null)
					xmlNode = node;
				else
					Files.push(new RemoteFile(this, node, null));
			}
			
			// Fire event to tell tree that new children have been loaded
			super.Load(depth);
			
			// Tell childern to load
			for each(var child:RemoteFile in Files)
			{
				trace("child.name=" + child.name);
				child.addEventListener("LoadComplete", OnLoadComplete);
				child.Load(depth - 1);
			}
			
			if(files.length == 0 || depth == 1)
				dispatchEvent(new Event("LoadComplete"));
		}
		
		protected function OnLoadComplete(e:Event = null):void
		{
			loadedCount++;
			trace("loadedCount=" + loadedCount);
			if (loadedCount == files.length)
				dispatchEvent(new Event("LoadComplete"));
		}

		protected function OnResponse(e:Event=null):void
		{
			trace("OnResponse");
			dispatchEvent(e);
		}
		
		protected function OnStatus(e:Event=null):void
		{
			trace("OnStatus");
			dispatchEvent(e);
		}
		
		protected function OnError(e:Event=null):void
		{
			trace("OnError" + e.toString());
			dispatchEvent(e);
		}
		
		protected function OnProgress(e:Event=null):void
		{
			trace("OnProgress");
			dispatchEvent(e);
		}
		
		protected function OnSecurityError(e:Event=null):void
		{
			trace("OnSecurityError");
			dispatchEvent(e);
		}
		
	}

}